package kortsoft.culcon.model;

import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.cfg.Configuration;

public class HibernateUtil {
	
	private static HibernateUtil hibernateUtil;
	private Configuration configuration;
	private SessionFactory sessionFactory;
	private ThreadLocal<Session> hibernateSessionThreadLocal = new ThreadLocal<Session>();
	private ThreadLocal<Transaction> hibernateTransactionThreadLocal = new ThreadLocal<Transaction>();
	
	public static HibernateUtil getInstance() {
		if (hibernateUtil == null) {
			hibernateUtil = new HibernateUtil();			
		}
		return hibernateUtil;
	}
	
	public Session currentSession() {
		if (hibernateSessionThreadLocal.get()==null) {
			hibernateSessionThreadLocal.set(buildSession());
		}
		return hibernateSessionThreadLocal.get();
	}
	
	public void startTransaction() {
		Transaction t = hibernateTransactionThreadLocal.get();
		if (t==null) {
			Session session = hibernateSessionThreadLocal.get();
			hibernateTransactionThreadLocal.set(session.beginTransaction());
		}
	}
	
	public void endTransaction() {
		Transaction transaction = hibernateTransactionThreadLocal.get();
		if (transaction !=null) {
			transaction.commit();
			hibernateTransactionThreadLocal.remove();
		}
	}
	
	public void closeSession() {
		Session session = hibernateSessionThreadLocal.get();
		if (session!=null) {
			session.close();
			hibernateSessionThreadLocal.remove();
		}
	}
	
	public void closeAll() {
		closeSession();
		sessionFactory.close();
	}

	private Session buildSession() {
		configuration = new Configuration().configure();
		sessionFactory = configuration.buildSessionFactory();
		Session session = sessionFactory.openSession();
		Transaction tx = session.beginTransaction();
		hibernateTransactionThreadLocal.set(tx);
		return session;
	}

}
